# -*- coding: utf-8 -*-
# Author   : ZhangQing
# Time     : 2025-08-04 23:27
# File     : project_sidebar.py
# Project  : codebuddy_craft
# Desc     :
# frontend/components/project_sidebar.py
import streamlit as st
import asyncio
from typing import Dict, Any, List, Optional


class ProjectSidebar:
    """项目侧边栏组件"""
    
    def __init__(self, api_client, state_manager):
        self.api_client = api_client
        self.state_manager = state_manager
    
    def render(self) -> Optional[Dict[str, Any]]:
        """渲染项目侧边栏"""
        
        # 新建项目按钮
        if st.button("➕ 新建项目", key="new_project_btn", type="primary"):
            self._show_create_project_dialog()
        
        st.markdown("---")
        
        # 获取项目列表
        projects = self._get_projects()
        
        if not projects:
            st.info("还没有项目，快来创建第一个吧！")
            return None
        
        # 项目筛选
        search_term = st.text_input("🔍 搜索项目", key="project_search")
        
        # 筛选项目
        if search_term:
            filtered_projects = [
                p for p in projects 
                if search_term.lower() in p['name'].lower() or 
                   search_term.lower() in p.get('description', '').lower()
            ]
        else:
            filtered_projects = projects
        
        # 项目列表
        selected_project = None
        
        st.subheader(f"📂 我的项目 ({len(filtered_projects)})")
        
        for project in filtered_projects:
            # 项目卡片
            with st.container():
                # 项目基本信息
                project_name = project['name']
                project_desc = project.get('description', '暂无描述')
                file_count = project.get('file_count', 0)
                tech_stack = project.get('tech_stack', '未指定')
                
                # 项目选择按钮
                if st.button(
                    f"📁 {project_name}",
                    key=f"select_project_{project['id']}",
                    help=f"{project_desc}\n技术栈: {tech_stack}\n文件数: {file_count}"
                ):
                    st.session_state['current_project'] = project
                    selected_project = project
                    st.experimental_rerun()
                
                # 项目详细信息
                with st.expander(f"ℹ️ 项目详情", expanded=False):
                    st.write(f"**描述:** {project_desc}")
                    st.write(f"**技术栈:** {tech_stack}")
                    st.write(f"**文件数量:** {file_count}")
                    st.write(f"**创建时间:** {project.get('created_at', 'Unknown')[:10]}")
                    st.write(f"**最后修改:** {project.get('updated_at', 'Unknown')[:10]}")
                    
                    # 项目操作按钮
                    col1, col2, col3 = st.columns(3)
                    
                    with col1:
                        if st.button("✏️ 编辑", key=f"edit_project_{project['id']}"):
                            self._show_edit_project_dialog(project)
                    
                    with col2:
                        if st.button("📤 导出", key=f"export_project_{project['id']}"):
                            self._export_project(project['id'])
                    
                    with col3:
                        if st.button("🗑️ 删除", key=f"delete_project_{project['id']}"):
                            self._show_delete_project_dialog(project)
                
                st.markdown("---")
        
        # 返回当前选中的项目
        current_project = st.session_state.get('current_project')
        if current_project:
            st.success(f"当前项目: {current_project['name']}")
            return current_project
        
        return selected_project
    
    def _get_projects(self) -> List[Dict[str, Any]]:
        """获取项目列表"""
        
        # 使用缓存避免重复请求
        cache_key = "user_projects"
        if cache_key in st.session_state:
            return st.session_state[cache_key]
        
        try:
            result = asyncio.run(self.api_client.get_projects())
            
            if result['code'] == 200:
                projects = result['data']['projects']
                st.session_state[cache_key] = projects
                return projects
            else:
                st.error(f"获取项目列表失败: {result['msg']}")
                return []
        
        except Exception as e:
            st.error(f"获取项目列表出错: {str(e)}")
            return []
    
    def _show_create_project_dialog(self):
        """显示创建项目对话框"""
        
        with st.expander("➕ 创建新项目", expanded=True):
            # 项目基本信息
            project_name = st.text_input(
                "项目名称 *",
                placeholder="输入项目名称",
                key="new_project_name"
            )
            
            project_desc = st.text_area(
                "项目描述",
                placeholder="简要描述项目功能和目标",
                key="new_project_desc"
            )
            
            # 项目类型
            project_type = st.selectbox(
                "项目类型 *",
                ["single", "multi"],
                format_func=lambda x: "单文件项目" if x == "single" else "多文件项目",
                key="new_project_type"
            )
            
            # 技术栈选择
            tech_stacks = [
                "Python", "JavaScript", "TypeScript", "React", "Vue.js",
                "Node.js", "Java", "Spring Boot", "C++", "Go",
                "Rust", "PHP", "Ruby", "HTML/CSS", "其他"
            ]
            
            tech_stack = st.selectbox(
                "技术栈 *",
                tech_stacks,
                key="new_project_tech_stack"
            )
            
            # 如果选择其他，显示输入框
            if tech_stack == "其他":
                tech_stack = st.text_input(
                    "请输入技术栈",
                    key="custom_tech_stack"
                )
            
            # 项目模板（针对多文件项目）
            if project_type == "multi":
                templates = {
                    "基础项目": "基本的项目结构",
                    "Web应用": "Web应用项目模板",
                    "API服务": "RESTful API 服务模板",
                    "数据分析": "数据分析项目模板",
                    "机器学习": "机器学习项目模板"
                }
                
                template = st.selectbox(
                    "项目模板",
                    list(templates.keys()),
                    help="选择预设的项目结构模板",
                    key="project_template"
                )
                
                st.info(f"📝 {templates[template]}")
            
            # 创建按钮
            col1, col2 = st.columns(2)
            
            with col1:
                if st.button("创建项目", key="confirm_create_project", type="primary"):
                    if project_name and tech_stack:
                        success = asyncio.run(self._create_project({
                            'name': project_name,
                            'description': project_desc,
                            'type': project_type,
                            'tech_stack': tech_stack
                        }))
                        
                        if success:
                            st.success(f"项目 {project_name} 创建成功！")
                            # 清除缓存，刷新项目列表
                            if "user_projects" in st.session_state:
                                del st.session_state["user_projects"]
                            st.experimental_rerun()
                        else:
                            st.error("项目创建失败")
                    else:
                        st.warning("请填写必填字段")
            
            with col2:
                if st.button("取消", key="cancel_create_project"):
                    st.experimental_rerun()
    
    def _show_edit_project_dialog(self, project: Dict[str, Any]):
        """显示编辑项目对话框"""
        
        st.info("项目编辑功能开发中...")
    
    def _show_delete_project_dialog(self, project: Dict[str, Any]):
        """显示删除项目确认对话框"""
        
        st.warning(f"⚠️ 确定要删除项目 '{project['name']}' 吗？")
        st.error("此操作将永久删除项目中的所有文件，且不可撤销！")
        
        # 输入确认
        confirm_text = st.text_input(
            f"请输入项目名称 '{project['name']}' 以确认删除:",
            key=f"delete_confirm_{project['id']}"
        )
        
        col1, col2 = st.columns(2)
        
        with col1:
            if st.button("确认删除", key=f"confirm_delete_project_{project['id']}", type="primary"):
                if confirm_text == project['name']:
                    success = asyncio.run(self._delete_project(project['id']))
                    
                    if success:
                        st.success(f"项目 {project['name']} 已删除")
                        # 清除缓存和当前选中项目
                        if "user_projects" in st.session_state:
                            del st.session_state["user_projects"]
                        if st.session_state.get('current_project', {}).get('id') == project['id']:
                            st.session_state['current_project'] = None
                        st.experimental_rerun()
                    else:
                        st.error("删除失败")
                else:
                    st.error("项目名称不匹配，请重新输入")
        
        with col2:
            if st.button("取消", key=f"cancel_delete_project_{project['id']}"):
                pass
    
    def _export_project(self, project_id: str):
        """导出项目"""
        
        try:
            with st.spinner("正在准备导出..."):
                result = asyncio.run(self.api_client.export_project(project_id))
            
            if result['code'] == 200:
                download_url = result['data']['zip_url']
                st.success("项目导出成功！")
                st.markdown(f"[📥 点击下载]({download_url})")
            else:
                st.error(f"导出失败: {result['msg']}")
        
        except Exception as e:
            st.error(f"导出出错: {str(e)}")
    
    async def _create_project(self, project_data: Dict[str, Any]) -> bool:
        """创建项目"""
        
        try:
            result = await self.api_client.create_project(project_data)
            return result['code'] == 200
        
        except Exception as e:
            st.error(f"创建项目失败: {str(e)}")
            return False
    
    async def _delete_project(self, project_id: str) -> bool:
        """删除项目"""
        
        try:
            # 注意：这里需要实现删除项目的API
            # result = await self.api_client.delete_project(project_id)
            # return result['code'] == 200
            
            # 暂时返回True，实际应该调用API
            return True
        
        except Exception as e:
            st.error(f"删除项目失败: {str(e)}")
            return False
